<script setup>
import StarterKit from "@tiptap/starter-kit";
import { Editor, EditorContent } from "@tiptap/vue-3";
// 富文本中的组件
// 每一项
import speak from "./TextEditConfig/Global_speak.js";
// 插入停顿
import Break from "./TextEditConfig/break.js";
// 取消诵读
import CancelRead from "./TextEditConfig/cancelread.js";
// 数字读音
import NumberPronunciation from "./TextEditConfig/numberPronunciation.js";

// import BLCOMMON from "bl-common-vue3";

// 修改文字发音
import Pronounce from "./TextEditConfig/pronounce.js";
// import EditBtns from './TextEditConfig/EditBtn.js'
import EditBtns from "./TextEditComponens/EditBtns.vue";
import { ref, onMounted, onUnmounted, computed, watch, nextTick } from "vue";
import { backspacePlugin } from "./helper/backspacePlugin.js";
import { pasteRules } from "./helper/pasteRules.js";
import { useStore } from "vuex";
import Document from "@tiptap/extension-document";
// 风险词检测组件
import RiskWordDetection from "../../../mixedCutCreat/components/riskWordDetecDrawer.vue";
// 素材库
import ChooseMaterial from "@/views/shotstack/EditingCenter/modules/bottomSet/components/chooseMaterial.vue";
// 风险词手风琴组件
import Risk_test from "./Risk_test.vue";

// 字幕特效设置
import SubtitleSpeciallyGoodEffectDialog from '@/views/shotstack/components/SubtitleSpeciallyGoodEffectDialog/index.vue'
const SubtitleSpeciallyGoodEffectDialogRef = ref()

// 字幕特效 tips 文案获取
import {getEffectsTips} from '@/common/utils/atherUtils.js'


// 工具函数
import {
  handleRichTextGlobalUpdate,
  textImportTorRichtext,
  max_text_length
} from "@/common/utils/richTextProcessing.js";
import { nanoid } from "nanoid";
const Risk_testRef = ref(null);

// 获取基础数据格式和处理富文本格式的工具函数
import {
  getSsmlcontent,
  estimateAudioDuration,
  processText,
  getTextWidthUsingCanvas,
  SensitiveWordsReplace,
  xLocation,
  resetXY,
  sizeData,
  splitTextAndRemoveCommas,
  subtitleHeightratio,
} from "@/views/shotstack/MuseMixedCut/utools/index.js";
// 字符数量统计
import CharacterCount from "@tiptap/extension-character-count";
// icon
import { DeleteOutlined } from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
// 文案库组件
import CopyLibraryModal from "@/components/AddTextModal/CopyLibraryModal.vue";
const props = defineProps({
  // tts项的id
  tts_id: {
    type: String,
    default: "",
  },
  // 用于展示的下标
  showIndex: {
    type: Number,
    default: 0,
  },
  // 本项的类型: 手动生成:text || 音频生成:audio
  tab_id: {
    type: String,
    default: "",
  },
});

const store = useStore();

// 抽屉中的使用缓存数据
const subTitle = computed(() => {
  return store.state.videoMixCut.Global_tts_config;
});

// 正在编辑的此项tts仓库数据
const current_editItem = computed(() => {
  if (subTitle.value) {
    const target = subTitle.value.configs.find(
      (ele) => ele.tts_id == props.tts_id
    );
    console.log(target, "本项编辑的tts");
    return target;
  } else {
    console.log(target, "本项编辑的tts");

    return {};
  }
});

// 当前编辑的字幕组(configs)的id
const currentId = computed(() => {
  return store.state.videoMixCut.global_edit_tts_id;
});

// 当前编辑字幕的类型(手动设置 或者 音频)
const tab_id = computed(() => {
  return subTitle.value?.configs_type;
});

// 判断是否禁用删除按钮
const disable_del_btn = computed(() => {
  // debugger
  const filterArr = subTitle.value.configs.filter(
    (ele) => ele.tab_id == props.tab_id
  );
  const flage = filterArr.length <= 1;
  return flage;
});

// 当前富文本的纯文字
const text = computed(() => {
  return !!editor.value ? editor.value.getText() : "";
});

// 当前编辑项的文字数组, 风险词会用到
const text_arr = computed(() => {
  const findItemTts = subTitle.value.configs.find(
    (ele) => ele.tts_id == props.tts_id
  );
  if (findItemTts) {
    return findItemTts.subtitle.map((ele) => ele.text).filter((ele) => !!ele);
  } else {
    return [];
  }
});

// 富文本实例
const editor = ref(null);
const limit = ref(max_text_length);
// 字数百分比
const percentage = computed(() => {
  return Math.round(
    (100 / limit.value) * editor.value.storage.characterCount.characters()
  );
});

// 将当前的数据转换为富文本
const getContent = () => {
  const targetData = subTitle.value.configs.find(
    (ele) => ele.tts_id == props.tts_id
  );
  // debugger
  if (!targetData?.ssmlContent) {
    return targetData.subtitle
      .map((ele) => {
        const text = ele.text;
        const id = ele.subtitle_id;
        // let ssml = ele.ssml;
        // 使用正则表达式在 <speak> 标签后添加 subId 和 tts_id
        // ssml = ssml.replace(/<speak([^>]*)>/, `<speak$1 subId="${id}" tts_id="${props.tts_id}">`);
        // return ssml
        if (text == "") {
          return `<speak subId="${id}" tts_id="${props.tts_id}"><span></span></speak>`;
        } else {
          return `<speak subId="${id}" tts_id="${props.tts_id}"><span>${text}</span></speak>`;
        }
      })
      .join("");
    // return `<speak subid="${targetData.subtitle[0].subtitle_id}" tts_id="${props.tts_id}"><span></span></speak>`
  } else {
    return targetData.ssmlContent;
  }
};

onMounted(() => {
  // debugger
  const content = getContent();
  const allCOnt = `<div>${content}</div>`;
  console.log(content, "content");
  editor.value = new Editor({
    extensions: [
      StarterKit.configure({
        // paragraph: false, // 段落
        // text:false, // 文本
        // listItem: false, // 列表
        // bulletList: false, // ul > li 列表
        blockquote: false, // 在编辑器中使用html标签
        codeBlock: false, // 代码块儿
        heading: false, // 标题拓展
        horizontalRule: false, // 分割线
        orderedList: false, // ol > li 列表
      }),
      Document,
      CancelRead,
      Break,
      NumberPronunciation,
      Pronounce,
      speak,
      // 富文本字数限制
      CharacterCount.configure({
        limit: max_text_length,
      }),
      backspacePlugin(() => {
        return editor.value;
      }),
      // 定义的粘贴规则
      pasteRules(() => {
        return editor.value;
      }),
    ],

    content: allCOnt,
    // 实例内容变化
    onUpdate: ({ editor }) => {
      // 富文本发生变化后, 实时同步更新仓库中的数据
      const jsonData = editor.getJSON();
      const content = editor.getHTML();

      handleRichTextGlobalUpdate({
        subTitle: subTitle.value,
        tts_id: props.tts_id,
        jsonData,
        content,
      });

      // store.commit("videoMixCut/INIT_GLOBALTTSCONFIG_CONGIG", subTitle.value);
      const findItemTts = subTitle.value.configs.find(
        (ele) => ele.tts_id == props.tts_id
      );
      if (findItemTts && findItemTts.tab_id != 'audio') {
        findItemTts.audio_url = ''
      }
      // debugger
      store.commit("videoMixCut/INIT_GLOBALTTSCONFIG_DATA", subTitle.value);
    },
    // 给编辑器渲染的节点添加class
    editorProps: {
      attributes: {
        class: "editor_container",
      },
    },
    enablePasteRules: false,
  });
});

const listenEditor = computed(() => {
  // debugger
  if (!editor.value) return null;
  const { state } = editor.value;
  // 选区为空
  if (state.selection.empty == true) {
    return false;
  } else {
    // 确保选区是文本选区
    // 使用 doc.textBetween 方法获取选区文本
    const text = state.doc.textBetween(
      state.selection.from,
      state.selection.to
    );
    // 存放选中的节点
    let selectedNodes = [];
    // 遍历每一个选区的范围
    state.selection.ranges.forEach((range) => {
      state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node) => {
        if (node.type.name == "speak") {
          selectedNodes.push(node);
        }
      });
    });
    return {
      text,
      selectedNodes,
    };
  }
});

watch(
  () => listenEditor.value,
  (nv, ov) => {
    if (!nv) {
      store.commit("videoMixCut/SET_SELECTION_DATA", {});
      return;
    }
    // store.commit("videoMixCut/MODIFY_SUBTITLES_TTSCONFIG", { text: nv.text })
    store.commit("videoMixCut/SET_SELECTION_DATA", nv);
    // 选择了一项
    if (nv.selectedNodes.length == 1) {
      // 获得选择的选区位置, 传递属性 使其高亮
    }
  }
);

// 当前正在编辑的富文本项的id
const editSubtitleData = computed(() => {
  if (editor.value == null) return null;
  // 假设`editor`是你的Tiptap编辑器实例
  const { selection } = editor.value.state;
  const { $from } = selection;
  // 获取当前光标所在的节点
  const node = $from.node($from.depth);
  if (node.content.content.length == 0) {
    return {
      id: node.attrs.subId,
      text: "",
    };
  } else {
    const ssmlData = getSsmlcontent(node.content.content);
    return {
      id: node.attrs.subId,
      text: ssmlData.text,
    };
  }
});

// 获取到当前富文本项的数据后存储到vuex, 用于手机组件和字体设置组件,同步修改次subtitle的样式数据
watch(
  () => editSubtitleData.value,
  (nv, ov) => {
    store.commit("videoMixCut/SET_EDIT_SUBTITLE_DATA", nv);
  }
);

// 抽屉中编辑的字幕组的id
const tts_id = computed(() => {
  console.log(
    store.state.videoMixCut.current_tts_id,
    "store.state.videoMixCut.current_tts_id"
  );
  return store.state.videoMixCut.current_tts_id;
});

const audioSrc = ref("");

// 侦听仓库中的音频播放信息
watch(
  () => store.state.videoMixCut.VideoPlayingData,
  (nv, ov) => {
    const dom = document.getElementById("Global_audioRef");
    if (nv.isPlay) {
      if (nv.changeUrl) {
        audioSrc.value = nv.audio_url;
      }
      nextTick(() => {
        //从头播放
        if (nv.reset) {
          dom.currentTime = 0;
          dom && dom.play();
        } else {
          dom && dom.play();
        }
        // store.commit('videoMixCut/SETVIDEOPLAYING_DATA', { isPlay: true })
      });
    } else {
      dom && dom.pause();
      // store.commit('videoMixCut/SETVIDEOPLAYING_DATA', { isPlay: false })
    }
  },
  {
    deep: true,
  }
);

const audioEnd = () => {
  store.commit("videoMixCut/SETVIDEOPLAYING_DATA", { isPlay: false });
};

// 销毁实例
onUnmounted(() => {
  editor.value.destroy();
});

// 删除字幕组
// 删除某项 - 不允许删除第一项
const deleteItem = () => {
  if (disable_del_btn.value) return;
  const id = props.tts_id;
  if (tab_id.value == "text") {
    const tts_texts = subTitle.value.configs.filter(
      (item) => item.tab_id == "text"
    );
    if (tts_texts.length == 1) return;
    const delIndex = subTitle.value.configs.findIndex(
      (item) => item.tts_id == id
    );
    if (delIndex != -1) {
      subTitle.value.configs.splice(delIndex, 1);
      store.commit("videoMixCut/INIT_GLOBALTTSCONFIG_DATA", subTitle.value);
    }
  } else {
    const tts_audios = subTitle.value.configs.filter(
      (item) => item.tab_id == "audio"
    );
    if (tts_audios.length == 1) return;
    const delIndex = subTitle.value.configs.findIndex(
      (item) => item.tts_id == id
    );
    if (delIndex != -1) {
      subTitle.value.configs.splice(delIndex, 1);
      store.commit("videoMixCut/INIT_GLOBALTTSCONFIG_DATA", subTitle.value);
    }
  }
};

// 计算文本的预计时长
const duration = computed({
  get() {
    let text = "";
    let time = 0;
    subTitle.value.configs.forEach((ele) => {
      if (ele.tab_id == props.tab_id && ele.tts_id == props.tts_id) {
        ele.subtitle.forEach((i) => {
          const data = processText(i.ssml);
          text += data.resultText;
          time += data.totalTime;
        });
      }
    });
    if (text) {
      // 用文本计算大约的时长
      const durationData = Math.ceil(+estimateAudioDuration(text));
      if (time) {
        // 如果有停顿的时间, 需要加上停顿时间
        time = time / 1000;
        return durationData + time;
      } else {
        return durationData;
      }
    } else {
      return 0;
    }
  },
});

// 风险词检测结束
const testOver = (risk_data) => {
  console.log(risk_data, "风险词检测结束");
  if (risk_data) {
    const target = subTitle.value.configs.find(
      (ele) => ele.tts_id == props.tts_id
    );
    target.risk_data = risk_data;
  }
};
// 风险词检测
const riskWordDetection = ref(null);
const riskWordDetnHandle = () => {
  const isImpty = text_arr?.value?.some((item) => item.trim().length > 0);
  console.log(isImpty);
  if (isImpty) {
    riskWordDetection.value &&
      riskWordDetection.value.showDrawer(text_arr?.value, "textEditing");
  } else {
    message.warning("请输入字幕");
  }
};

// 富文本更新方法
const updateRichText = () => {
  // debugger
  console.log(props.tts_id);
  const content = getContent();
  editor.value.commands.setContent(`<div>${content}</div>`);
};

// 获取当前富文本的文字字数
const text_num = computed(() => {
  if (!editor.value) return 0;
  return editor.value?.storage?.characterCount?.characters() || 0;
});
// 打开素材库弹窗
const materiallibraryShow = ref(false); //控制素材库弹框显示
// 打开文案库弹窗
let copyLibraryModal = ref(null); //文案库导入组件实例
const openCopyLibraryModal = () => {
  copyLibraryModal.value && copyLibraryModal.value.showModal();
};
// 获得字体大小转换的比例
const scaleData = computed(() => {
  const { showHeight, showWidth } = store.state.videoMixCut.VideoMashup;
  return resetXY(showHeight, showWidth);
});
// 从仓库中拿到各镜头组数据
const resource_data = computed(() => {
  return store.state.videoMixCut.VideoMashup.resource_data;
});
// 素材选择回调
const closeChooseMaterial = async (data) => {
  textImportTorRichtext({
    data,
    subTitle,
    props,
    sizeData,
    current_tts_data: current_editItem,
    getContent,
    editor,
    copyLibraryModal,
    subtitleHeightratio,
    tts_id,
    type: "Global",
    currentDrawerIndex: null,
  });
};

// 字幕特效设置
const subtitleSpecialEffects = () => {
  console.log(current_editItem.value, '本项编辑的 tts??');
  const subtitle_effects = current_editItem.value?.subtitle_effects;
  SubtitleSpeciallyGoodEffectDialogRef.value?.open({subtitle_effects})
}

const updateTextEffect_config = (confige) => {
  console.log(confige,'修改后的confige字幕特效');
  current_editItem.value.subtitle_effects = confige;
}

defineExpose({
  editor,
  duration,
  updateRichText,
  text_num,
  limit,
  tts_id: props.tts_id,
});
</script>

<template>
  <div class="TextEditing">
    <div class="manual_title">
      <span class="title_text">字幕{{ props.showIndex + 1 }}
        <a-button size="small" type="link" class="import_meatiner_btn" @click="openCopyLibraryModal">文案库导入</a-button>
        <a-button size="small" type="link" class="import_meatiner_btn" @click="subtitleSpecialEffects">字幕特效设置{{ getEffectsTips(current_editItem) }}</a-button>

      </span>
      <div class="operation">
        <span style="color: #737a87; font-size: 12px">shift + enter 折行</span>
        <a-button @click="riskWordDetnHandle()" size="small"
          style="font-size: 12px; padding-top: 1px; height: 22px">风险词检测</a-button>
        <!-- <a-button @click="Risk_testRef?.foldOrOpen()" size="small"
          style="font-size: 12px; padding-top: 1px; height: 22px;">风险词检测</a-button> -->
        <a-button style="font-size: 12px; height: 22px" @click="deleteItem" :disabled="disable_del_btn"
          size="small">删除</a-button>
      </div>
    </div>

    <div class="content">
      <editor-content :editor="editor"> </editor-content>

      <div class="btn_box">
        <!-- 底部btn按钮 -->
        <EditBtns :editor="editor" style="outline: none"></EditBtns>

        <div class="edit_show_msg">
          <!-- 文本预计时长 -->
          <div class="duration" v-show="tab_id == 'text'">
            预计时长: <span class="time_content">{{ duration }}</span>秒
          </div>

          <!-- 文本字数, 进度统计 -->
          <div v-if="!!editor" :class="{
            'character-count': true,
            'character-count--warning': text_num === limit,
          }">
            <svg height="20" width="20" viewBox="0 0 20 20">
              <circle r="10" cx="10" cy="10" fill="#e9ecef" />
              <circle r="5" cx="10" cy="10" fill="transparent" stroke="currentColor" stroke-width="10"
                :stroke-dasharray="`calc(${percentage} * 31.4 / 100) 31.4`" transform="rotate(-90) translate(-20)" />
              <circle r="6" cx="10" cy="10" fill="white" />
            </svg>
            {{ text_num }} / {{ limit }}
            <br />
          </div>
        </div>
      </div>
    </div>
    <audio :src="audioSrc" v-show="false" ref="audioRef" id="Global_audioRef" @ended="audioEnd"></audio>

    <!-- <Risk_test ref="Risk_testRef" :disableSubmit="!text.length" :type="'tts_config'" :text_arr="text_arr"
      :risk_data="current_editItem?.risk_data || null" @testOver="testOver">
    </Risk_test> -->
    <RiskWordDetection ref="riskWordDetection" />
    <!-- 素材库弹窗 -->
    <ChooseMaterial :isClip="true" material_type="text" :multiple="true" :visible="materiallibraryShow"
      @close="closeChooseMaterial($event, 'material_type')" />
    <!-- 文案库 -->
    <CopyLibraryModal ref="copyLibraryModal" @importSuccess="closeChooseMaterial" />

      <!-- 字幕特效弹窗 -->
  <SubtitleSpeciallyGoodEffectDialog ref="SubtitleSpeciallyGoodEffectDialogRef" @updateTextEffect_config="updateTextEffect_config"></SubtitleSpeciallyGoodEffectDialog>
  </div>
</template>

<style lang="less" scoped>
/* Basic editor styles */
.TextEditing {
  background-color: #f6f8fa;
  padding: 16px;
  margin-top: 10px;

  .import_meatiner_btn {
    opacity: 0;
  }

  &:hover .import_meatiner_btn {
    opacity: 1;
  }

  // 标题样式
  .manual_title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;

    .title_text {
      font-size: 14px;
      color: #0c0d0e;
      font-weight: 600;
    }

    .operation {
      display: flex;
      align-items: center;
      gap: 10px;

      .time {
        background-color: #fff;
        border: 1px solid #dde2e9;
        font-size: 13px;
        color: #42464e;
        border-radius: 3px;
        padding: 0px 7px;
        cursor: pointer;

        &:hover {
          border-color: #3261fb;
        }
      }

      .disable_delete_btn {
        cursor: not-allowed;
        border-color: #dde2e9;
        color: #c7ccd6;

        &:hover {
          cursor: not-allowed;
          border-color: #dde2e9;
          color: #c7ccd6;
        }
      }
    }
  }

  .content {
    background-color: #ffffff;
    padding-bottom: 10px;

    :deep(.ProseMirror) {
      outline: none !important;
      min-height: 120px;
    }

    .btn_box {
      padding: 0 10px;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .edit_show_msg {
        display: flex;
        align-items: center;
        gap: 10px;

        .duration {
          color: #737a87;

          .time_content {
            // color: var(--ss-primary-5);
          }
        }

        // 文本上限提示
        .character-count {
          align-items: center;
          color: var(--ss-primary-5);
          display: flex;
          font-size: 0.75rem;
          gap: 0.5rem;

          svg {
            color: var(--ss-primary-5);
          }

          &--warning,
          &--warning svg {
            color: red;
          }
        }
      }
    }
  }
}
</style>
